﻿// cast1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

//#include "pch.h"
//#include <iostream>
//#include <opencv2/opencv.hpp>
//using namespace cv;
////读取图片
//int main()
//{
//	Mat test = imread("H:\\图片\\test.jpg");
//	imshow("显示图片", test);
//	waitKey();
//
//	return 0;
//}
 
//#include "pch.h"
//#include <opencv2\opencv.hpp>  
//using namespace cv;
//int main()
//{
//	//【1】从摄像头读入视频
//	VideoCapture capture(0);
//
//	//【2】循环显示每一帧
//	while (1)
//	{
//		Mat frame;  //定义一个Mat变量，用于存储每一帧的图像
//		capture >> frame;  //读取当前帧
//		imshow("读取视频", frame);  //显示当前帧
//		waitKey(30);  //延时30ms
//		//目前关闭摄像头不好使
//		/*if (waitKey(30) == 'q')
//			break; */
//	}
//	return 0;
//}



////图像模糊
//#include "pch.h"
//#include "opencv2/highgui/highgui.hpp" 
//#include "opencv2/imgproc/imgproc.hpp" 
//using namespace cv;
//int main()
//{
//	//【1】载入原始图
//	Mat srcImage = imread("H:\\图片\\test.jpg");
//
//	//【2】显示原始图
//	imshow("均值滤波【原图】", srcImage);
//
//	//【3】进行均值滤波操作
//	Mat dstImage;
//	blur(srcImage, dstImage, Size(7, 7));
//
//	//【4】显示效果图
//	imshow("均值滤波【效果图】", dstImage);
//
//	waitKey(0);
//}


//#include "pch.h"
//#include <opencv2/opencv.hpp>
//#include<opencv2/imgproc/imgproc.hpp>
//using namespace cv;
//
//int main()
//{
//	//【0】载入原始图  
//	Mat srcImage = imread("H:\\图片\\test.jpg");  //工程目录下应该有一张名为1.jpg的素材图
//	imshow("【原始图】Canny边缘检测", srcImage); 	//显示原始图 
//	Mat dstImage, edge, grayImage;	//参数定义
//
//	//【1】创建与src同类型和大小的矩阵(dst)
//	dstImage.create(srcImage.size(), srcImage.type());
//
//	//【2】将原图像转换为灰度图像
//	//此句代码的OpenCV2版为：
//	//cvtColor( srcImage, grayImage, CV_BGR2GRAY );
//	//此句代码的OpenCV3版为：
//	cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);
//
//	//【3】先用使用 3x3内核来降噪
//	blur(grayImage, edge, Size(3, 3));
//
//	//【4】运行Canny算子
//	Canny(edge, edge, 3, 9, 3);
//
//	//【5】显示效果图 
//	imshow("【效果图】Canny边缘检测", edge);
//
//	waitKey(0);
//
//	return 0;
//}



//人脸检测
#include "pch.h"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

#include <iostream>
#include <stdio.h>

using namespace std;
using namespace cv;

void detectAndDisplay(Mat frame);

//--------------------------------【全局变量声明】----------------------------------------------
//		描述：声明全局变量
//-------------------------------------------------------------------------------------------------
//注意，需要把"haarcascade_frontalface_alt.xml"和"haarcascade_eye_tree_eyeglasses.xml"这两个文件复制到工程路径下
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);

//-----------------------------------【main( )函数】--------------------------------------------
//		描述：控制台应用程序的入口函数，我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(void)
{
	VideoCapture capture;
	Mat frame;


	//-- 1. 加载级联（cascades）
	if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading\n"); return -1; };
	if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading\n"); return -1; };

	//-- 2. 读取视频
	capture.open(0);
	if (capture.isOpened())
	{
		for (;;)
		{
			capture >> frame;

			//-- 3. 对当前帧使用分类器（Apply the classifier to the frame）
			if (!frame.empty())
			{
				detectAndDisplay(frame);
			}
			else
			{
				printf(" --(!) No captured frame -- Break!"); break;
			}

			int c = waitKey(10);
			if ((char)c == 'c') { break; }

		}
	}
	return 0;
}


void detectAndDisplay(Mat frame)
{
	std::vector<Rect> faces;
	Mat frame_gray;

	cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
	equalizeHist(frame_gray, frame_gray);

	//-- 人脸检测
	//此句代码的OpenCV2版为：
	face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
	//此句代码的OpenCV3版为：
   // face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );


	for (size_t i = 0; i < faces.size(); i++)
	{
		Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
		ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);

		Mat faceROI = frame_gray(faces[i]);
		std::vector<Rect> eyes;

		//-- 在脸中检测眼睛
		//此句代码的OpenCV2版为：
		eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
		//此句代码的OpenCV3版为：
	  //  eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );

		for (size_t j = 0; j < eyes.size(); j++)
		{
			Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
			int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
			circle(frame, eye_center, radius, Scalar(255, 0, 0), 3, 8, 0);
		}
	}
	//-- 显示最终效果图
	imshow(window_name, frame);
}